﻿#region Using directives
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
#endregion

namespace Blazorise.Modules
{
    /// <summary>
    /// Contracts for the various utilites JS module.
    /// </summary>
    public interface IJSUtilitiesModule : IBaseJSModule
    {
        /// <summary>
        /// Adds a classname to the specified element.
        /// </summary>
        /// <param name="elementRef">Reference to the rendered element.</param>
        /// <param name="classname">CSS classname to add.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        ValueTask AddClass( ElementReference elementRef, string classname );

        /// <summary>
        /// Removes a classname from the specified element.
        /// </summary>
        /// <param name="elementRef">Reference to the rendered element.</param>
        /// <param name="classname">CSS classname to remove.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        ValueTask RemoveClass( ElementReference elementRef, string classname );

        /// <summary>
        /// Toggles a classname on the given element.
        /// </summary>
        /// <param name="elementRef">Reference to the rendered element.</param>
        /// <param name="classname">CSS classname to toggle.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        ValueTask ToggleClass( ElementReference elementRef, string classname );

        /// <summary>
        /// Adds a classname to the body element.
        /// </summary>
        /// <param name="classname">CSS classname to add.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        ValueTask AddClassToBody( string classname );

        /// <summary>
        /// Removes a classname from the body element.
        /// </summary>
        /// <param name="classname"></param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        ValueTask RemoveClassFromBody( string classname );

        /// <summary>
        /// Indicates if parent element has a specified classname.
        /// </summary>
        /// <param name="elementRef">Reference to the rendered element.</param>
        /// <param name="classname">CSS classname to check.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        ValueTask<bool> ParentHasClass( ElementReference elementRef, string classname );

        /// <summary>
        /// Sets focus to the given element.
        /// </summary>
        /// <param name="elementRef">Reference to the rendered element.</param>
        /// <param name="elementId">ID of the rendered element.</param>
        /// <param name="scrollToElement">If true, scrolls to the element.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        ValueTask Focus( ElementReference elementRef, string elementId, bool scrollToElement );

        /// <summary>
        /// Selects the given element.
        /// </summary>
        /// <param name="elementRef">Reference to the rendered element.</param>
        /// <param name="elementId">ID of the rendered element.</param>
        /// <param name="focus">If true, it will focus to the element.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        ValueTask Select( ElementReference elementRef, string elementId, bool focus );

        /// <summary>
        /// Scrolls the view to the given anchor element.
        /// </summary>
        /// <param name="anchorTarget">Anchor element id.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        ValueTask ScrollAnchorIntoView( string anchorTarget );

        /// <summary>
        /// Sets the caret to the specified position.
        /// </summary>
        /// <param name="elementRef">Reference to the rendered element.</param>
        /// <param name="caret">Caret position.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        ValueTask SetCaret( ElementReference elementRef, int caret );

        /// <summary>
        /// Gets the caret position.
        /// </summary>
        /// <param name="elementRef">Reference to the rendered element.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        ValueTask<int> GetCaret( ElementReference elementRef );

        /// <summary>
        /// Updates the input with the specified value.
        /// </summary>
        /// <param name="elementRef">Reference to the rendered element.</param>
        /// <param name="value">New element value.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        ValueTask SetTextValue( ElementReference elementRef, object value );

        /// <summary>
        /// Apply the html property to the element.
        /// </summary>
        /// <param name="elementRef">Reference to the rendered element.</param>
        /// <param name="property">Property name.</param>
        /// <param name="value">Property value.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        ValueTask SetProperty( ElementReference elementRef, string property, object value );

        /// <summary>
        /// Gets the element info.
        /// </summary>
        /// <param name="elementRef">Reference to the rendered element.</param>
        /// <param name="elementId">ID of the rendered element.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        ValueTask<DomElement> GetElementInfo( ElementReference elementRef, string elementId );

        /// <summary>
        /// Gets the User Agent name.
        /// </summary>
        /// <returns>A task that represents the asynchronous operation.</returns>
        ValueTask<string> GetUserAgent();

        /// <summary>
        /// Copies the specified element content to the clipboard.
        /// </summary>
        /// <param name="elementRef">Reference to the rendered element.</param>
        /// <param name="elementId">ID of the rendered element.</param>
        /// <returns>A task that represents the asynchronous operation.</returns>
        ValueTask CopyToClipboard( ElementReference elementRef, string elementId );
    }
}
